﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using MvcWechat.Common;

namespace MvcWechat.Services
{
    public class Util
    {
        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //直接确认，否则打不开    
            return true;
        }
        static Type t = typeof(Util);
        /// <summary>
        /// 创建时间戳
        /// </summary>
        /// <returns></returns>
        public static long CreateTimestamp()
        {
            return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        }
        /// <summary>
        /// Sha1
        /// </summary>
        /// <param name="orgStr"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static string Sha1(string orgStr, string encode = "UTF-8")
        {
            var sha1 = new SHA1Managed();
            var sha1bytes = System.Text.Encoding.GetEncoding(encode).GetBytes(orgStr);
            byte[] resultHash = sha1.ComputeHash(sha1bytes);
            string sha1String = BitConverter.ToString(resultHash).ToLower();
            sha1String = sha1String.Replace("-", "");
            return sha1String;
        }
        /// <summary>
        /// 下载
        /// </summary>
        /// <param name="url"></param>
        /// <param name="stream"></param>
        public static void Download(string url, Stream stream)
        {
            WebClient wc = new WebClient();
            var data = wc.DownloadData(url);
            foreach (var b in data)
            {
                stream.WriteByte(b);
            }
        }
        public static string ReturnText(string text)
        {
            //string text1 = "";
            //switch (text)
            //{
            //    case "1": text1 = GetJoke(); break;
            //    default: text1 = "抱歉，这个不能理解..."; break;
            //}
            return text;
        }
        public static string GetJoke()
        {
            var url = "http://www.kuitao8.com/api/joke";
            var res = HttpRequestGet(url);
            if (res.status == 1)
            {
                return res.content;
            }
            else
            {
                return "没有笑话了！";
            }

        }
        public static dynamic HttpRequestGet(string url, string encoding = "UTF8",int timeout=3)
        {
            ServicePointManager.DefaultConnectionLimit = 200;
            //设置https验证方式
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback =
                        new RemoteCertificateValidationCallback(CheckValidationResult);
            }
            var client = new HttpClient();
            var result = client.GetAsync(url).Result;
            if (!result.IsSuccessStatusCode) return string.Empty;
            var _result = result.Content.ReadAsStringAsync().Result;
            Logger.Debug(typeof(OAuth2API), string.Format("HttpRequestGet 1, _result:{0}", _result));
            if (_result.Contains("40029") && timeout>0)  //如果错误再执行两次
            {
                _result = HttpRequestGet(url, encoding,--timeout);
            }
            Logger.Debug(typeof(OAuth2API), string.Format("HttpRequestGet 2, _result:{0}", _result));
            return DynamicJson.Parse(_result);
        }
        public static async Task<dynamic> HttpRequestPost(string url, string requestJson, string encoding = "UTF8")
        {
            HttpContent httpContent = new StringContent(requestJson);
            httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var client = new HttpClient();

            var result = await client.PostAsync(url, httpContent);
            if (!result.IsSuccessStatusCode) return string.Empty;
            //return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result);
            return await result.Content.ReadAsStringAsync();
        }
        public static string PostWebRequest(string postUrl, string paramData, string encoding = "UTF8", CookieContainer cookie = null)
        {
            string ret = string.Empty;

            byte[] byteArray = Encoding.GetEncoding("GB2312").GetBytes(paramData); //转化
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
            webReq.Method = "POST";
            webReq.ContentType = "application/x-www-form-urlencoded;charset=gb2312";
            webReq.KeepAlive = true;
            webReq.UserAgent = "Opera/9.80 (Android 4.0.3; Linux; Opera Mobi/ADR-1210241554) Presto/2.11.355 Version/12.10";
            if (cookie != null)
            {
                webReq.CookieContainer = cookie;
            }
            webReq.ContentLength = byteArray.Length;
            Stream newStream = webReq.GetRequestStream();
            newStream.Write(byteArray, 0, byteArray.Length);//写入参数
            newStream.Close();
            HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
            ret = sr.ReadToEnd();
            sr.Close();
            response.Close();
            newStream.Close();

            return ret;
        }


        /// <summary>
        /// 使用Post方法获取字符串结果
        /// </summary>
        /// <param name="url"></param>
        /// <param name="cookieContainer"></param>
        /// <param name="postStream"></param>
        /// <param name="fileDictionary">需要上传的文件，Key：对应要上传的Name，Value：本地文件名</param>
        /// <returns></returns>
        public static string HttpRequestPost(string url, Dictionary<string, string> fileDictionary = null, string encoding = "UTF8")
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.Timeout = 100;

            var postStream = new MemoryStream();
            #region 处理Form表单文件上传
            var formUploadFile = fileDictionary != null && fileDictionary.Count > 0;//是否用Form上传文件
            if (formUploadFile)
            {
                //通过表单上传文件
                string boundary = "----" + DateTime.Now.Ticks.ToString("x");

                string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";

                foreach (var file in fileDictionary)
                {
                    try
                    {
                        var fileName = file.Value;
                        //准备文件流
                        using (var fileStream = new FileStream(fileName, FileMode.Open))
                        {
                            var formdata = string.Format(formdataTemplate, file.Key, fileName);
                            var formdataBytes = Encoding.ASCII.GetBytes(postStream.Length == 0 ? formdata.Substring(2, formdata.Length - 2) : formdata);//第一行不需要换行
                            postStream.Write(formdataBytes, 0, formdataBytes.Length);

                            //写入文件
                            byte[] buffer = new byte[1024];
                            int bytesRead = 0;
                            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                postStream.Write(buffer, 0, bytesRead);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                //结尾
                var footer = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                postStream.Write(footer, 0, footer.Length);

                request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            }
            else
            {
                request.ContentType = "application/x-www-form-urlencoded";
            }
            #endregion

            request.ContentLength = postStream != null ? postStream.Length : 0;
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            request.KeepAlive = true;
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";

            #region 输入二进制流
            if (postStream != null)
            {
                postStream.Position = 0;

                //直接写入流
                Stream requestStream = request.GetRequestStream();

                byte[] buffer = new byte[1024];
                int bytesRead = 0;
                while ((bytesRead = postStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    requestStream.Write(buffer, 0, bytesRead);
                }
                postStream.Close();//关闭文件访问
            }
            #endregion

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(responseStream, Encoding.GetEncoding(encoding)))
                {
                    string retString = myStreamReader.ReadToEnd();
                    return retString;
                }
            }
        }
        public static string GetOpenIdByCode()
        {
            var debug = System.Configuration.ConfigurationManager.AppSettings["Debug"].ToLower();
            if (debug == "true")
            {
                Logger.Debug(t, "GetOpenIdByCode debug true :" + debug);
                //test  
                return "oZh39wvzaQXJ3BEg4YDPYLxBAhpk"; //肥胖就是力量 
            }
            else
            {
                try
                {
                    //正式环境
                    string openid = "";
                    if (HttpContext.Current.Session["openid"] != null && HttpContext.Current.Session["openid"].ToString() != "")  //&& HttpRuntime.Cache["info" + openid] != null
                    {
                        openid = HttpContext.Current.Session["openid"].ToString();
                        Logger.Debug(t, "is session openid:" + openid);
                    }
                    else
                    {
                        if (HttpContext.Current.Request.QueryString["code"] != null && HttpContext.Current.Request.QueryString["code"] != "")
                        {
                            string code = HttpContext.Current.Request.QueryString["code"];
                            try
                            {
                                openid = GetOpenIdByView(openid, code);
                            }
                            catch (Exception ex)
                            {
                                Logger.Debug(t, "get userOauth error:" + ex.Message);
                                throw ex;
                            }
                        }
                        else
                        {
                            if (HttpContext.Current.Request.UrlReferrer != null)
                            {
                                var query = HttpContext.Current.Request.UrlReferrer.Query;
                                if (query.Contains("?"))
                                {
                                    query = query.Substring(1);
                                    var urlParams = query.Split('&');

                                    Dictionary<string, string> urlKeyVals = new Dictionary<string, string>();
                                    for (int i = 0; i < urlParams.Length; i++)
                                    {
                                        if (urlParams[i] != "")
                                        {
                                            var temp = urlParams[i].Split('=');
                                            urlKeyVals.Add(temp[0], temp[1]);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                    var code = urlKeyVals["code"];
                                    openid = GetOpenIdByView(openid, code);
                                }
                                else
                                    openid = "code";
                            }
                            else
                                openid = "code";
                        }
                    }
                    return openid;
                }
                catch (Exception ex)
                {
                    Logger.Debug(t, "GetOpenIdByCode debug true :" + ex.Message);
                    throw;
                }
               
            }
        }
       private static string GetOpenIdByView(string openid, string code)
        {
            ConfigSettings config = CommonPage.GetConfigSettings();
            var userOauth = OAuth2API.GetAccessToken(code, config.AppIDByWX, config.AppSecretByWX);

            Logger.Debug(t, string.Format("is QueryString code:{0},userOauth:{1}", code, userOauth.ToString()));
            if (userOauth != null)
            {
                if (userOauth.ToString().Contains("openid"))
                {
                    openid = userOauth.openid;
                    //如果保存自定义菜单则需要执行以下
                    if (config.IsUseCustomerMenu == "true" && HttpRuntime.Cache["info" + openid] == null)
                    {
                        //查询数据库看是否有此openid的信息
                        var weixinInfo = OAuth2API.GetUserInfo(userOauth.access_token, userOauth.openid);
                        Logger.Debug(t, string.Format("OAuth2API.GetUserInfo,userInfo.ToString():{0}", weixinInfo.ToString()));
                        var v = BasicAPI.AddUserInfo(CommonPage.getKey(),JsonConvert.SerializeObject(weixinInfo));
                        Logger.Debug(t, string.Format("BasicAPI.AddUserInfo GetOpenIdByCode result:{0}", v));
                        SetCache("info" + openid, "1", "600");

                        //{"openid":"oCfARuNyrq7lNQfX0GsRo6PJJn78","nickname":"何平子","sex":1,"language":"zh_CN","city":"深圳","province":"广东","country":"中国","headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/mzzia4wQxJ2Ur0ic95jvnArCRpOR561Pj5RpFIAKNibdhaREgHBbttd7DGf5l118GsMwxaia29NM3nCatMQyDQtEWg\/132","privilege":[]}
                    }
                    Logger.Debug(t, string.Format("is QueryString code:{0},openid:{1}", code, userOauth.openid));
                    HttpContext.Current.Session["openid"] = openid;
                }
                else
                {
                    Logger.Debug(t, string.Format("is QueryString code:{0},userOauth.ToString():{1}", code, userOauth.ToString()));
                    openid = "user";
                }
            }
            else
            {
                openid = "user";
            }
            return openid;
        }
       /// <summary>
       /// 设置缓存
       /// </summary>
       /// <param name="key"></param>
       /// <param name="value"></param>
       /// <param name="minutes"></param>
       public static void SetCache(string key, string value, string minutes = "10")
       {
           int _minutes = 0;
           int.TryParse(minutes, out _minutes);
           //如果不设置默认10分钟
           HttpRuntime.Cache.Insert(key, value, null, DateTime.Now.AddMinutes(_minutes == 0 ? 10 : _minutes), TimeSpan.Zero);
       }
        //长网址转短网址
        public static string GetShortUrlByLongUrl(string longurl, string aToken)
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            dict.Add("action", "long2short");
            dict.Add("long_url", longurl);
            var url = HttpRequestPost(string.Format("https://api.weixin.qq.com/cgi-bin/shorturl?access_token={0}", aToken), JsonConvert.SerializeObject(dict));

            return url.ToString();
        }

    }
}